﻿using System.Globalization;
using System.Net;
using Ding.HttpHelper;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using SelfService.HaiTai.Models;
using SelfService.Model.Interface;
using SelfService.Model.Models;
using TT;
using WalkingTec.Mvvm.Core;
using Web.Models.His;

namespace SelfService.HaiTai
{
    public class HaiTaiOrder : IHisOrder
    {
        private readonly IOptions<AppSettings> _options;
        private readonly WTMContext _wtm;

        public HaiTaiOrder(IOptions<AppSettings> options, WTMContext wtm)
        {
            _options = options;
            _wtm = wtm;
        }
        
        /// <summary>
        /// 缴费
        /// </summary>
        /// <param name="order"></param>
        /// <param name="pay"></param>
        /// <returns></returns>
        public async Task<ResultDetail<bool>> Pay(IOrder order, SysPay pay)
        {
            HttpResult result = default;
            var postData = new PayValidate();
            postData.Jslsh = order.TradeNo;
            postData.Paylsh = pay.SerialsNumber;
            postData.OrderId = pay.OutOrderNo;
            postData.Paydate = pay.PayTime?.ToString("yyyy-MM-dd HH:mm:ss");
            postData.UserId = _wtm.LoginUserInfo.ITCode;
            switch (pay.PayType.Name)
            {
                case "微信":
                    postData.WX = pay.Amount.ToString(CultureInfo.InvariantCulture);
                    break;
                case "支付宝":
                    postData.ZFB = pay.Amount.ToString(CultureInfo.InvariantCulture);
                    break;
                case "现金":
                    postData.XJ = pay.Amount.ToString(CultureInfo.InvariantCulture);
                    break;
                case "诊疗卡":
                    postData.CZK = pay.Amount.ToString(CultureInfo.InvariantCulture);
                    break;
            }
            var httpItem = new HttpItem()
            {
                URL = $"{this._options.Value.HisUrl}/GetValue",
                Method = "POST",
                ContentType = "application/json",
                Postdata = JsonConvert.SerializeObject(postData)
            };
            try
            {
                await Task.Run(() =>
                {
                    result = new HttpHelper().GetHtml(httpItem);
                });
                if (result.Html.TryJsonParse(out HisResult<object> response))
                {
                    if (response.ResultCode == "0")
                    {
                        if (result.Html.TryJsonParse(out HisResult<HisPayResult[]> res) && res.Data?.Length > 0)
                        {
                            if (res.Data.First().RetMsg.Split('|').Length > 1)
                            {
                                order.TradeNo = res.Data.First().RetMsg.Split('|')[1] + "01";
                            }
                        }
                        return new ResultDetail<bool>()
                        {
                            Message = response.ErrorMsg,
                            Request = httpItem.Postdata,
                            Response = result.Html
                        };
                    }
                    else
                    {
                        return new ResultDetail<bool>()
                        {
                            Code = 1,
                            Message = response.ErrorMsg,
                            Request = httpItem.Postdata,
                            Response = result.Html
                        };
                    }
                }
                return new ResultDetail<bool>()
                {
                    Code = 1,
                    Message = "缴费失败, 返回数据解析异常.",
                    Request = httpItem.Postdata,
                    Response = result.Html
                };
            }
            catch (Exception e)
            {
                return new ResultDetail<bool>()
                {
                    Code = 1,
                    Message = $"缴费异常:{JsonConvert.SerializeObject(e)}",
                    Request = httpItem.Postdata
                };
            }
        }

        /// <summary>
        /// 充值
        /// </summary>
        /// <param name="pay"></param>
        /// <param name="patient"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<ResultDetail<bool>> AddCredit(SysPay pay, IPatient patient)
        {
            if (pay.PayType.Name != "微信" && pay.PayType.Name != "支付宝" && pay.PayType.Name != "现金")
            {
                return new ResultDetail<bool>()
                {
                    Code = 1,
                    Message = "不支持的充值方式",
                    Data = false
                };
            }
            HttpResult result = default;
            var postData = new AddCreditValidate();
            postData.Paylsh = pay.SerialsNumber;
            postData.OrderId = pay.OutOrderNo;
            postData.MacAddress = _wtm?.LoginUserInfo?.ITCode ?? pay.UpdateBy;
            postData.UserId = _wtm?.LoginUserInfo?.ITCode ?? pay.UpdateBy;
            postData.Amt = pay.Amount.ToString(CultureInfo.InvariantCulture);
            postData.CardNo = patient.IdCardNo;
            postData.CardType = "2";
            postData.TranType = pay.PayType.Name == "支付宝" ? "ZFB" : pay.PayType.Name == "微信" ? "WX" :  pay.PayType.Name == "微信" ? "XJ" : "";
            var httpItem = new HttpItem()
            {
                URL = $"{this._options.Value.HisUrl}/GetValue",
                Method = "POST",
                ContentType = "application/json",
                Postdata = JsonConvert.SerializeObject(postData)
            };
            try
            {
                await Task.Run(() =>
                {
                    result = new HttpHelper().GetHtml(httpItem);
                });
                if (result.StatusCode != HttpStatusCode.OK)
                {
                    return new ResultDetail<bool>()
                    {
                        Code = 1,
                        Message = "充值失败, 返回状态码异常.",
                        Request = httpItem.Postdata,
                        Response = result.StatusDescription
                    };
                }
                if (result.Html.TryJsonParse(out HisResult<object> response))
                {
                    if (response.ResultCode == "0")
                    {
                        return new ResultDetail<bool>()
                        {
                            Message = response.ErrorMsg,
                            Request = httpItem.Postdata,
                            Response = result.Html
                        };
                    }
                    else
                    {
                        return new ResultDetail<bool>()
                        {
                            Code = 1,
                            Message = response.ErrorMsg,
                            Request = httpItem.Postdata,
                            Response = result.Html
                        };
                    }
                }
                return new ResultDetail<bool>()
                {
                    Code = 1,
                    Message = "充值失败, 返回数据解析异常.",
                    Request = httpItem.Postdata,
                    Response = result.Html
                };
            }
            catch (Exception e)
            {
                return new ResultDetail<bool>()
                {
                    Code = 1,
                    Message = $"充值异常:{JsonConvert.SerializeObject(e)}",
                    Request = httpItem.Postdata
                };
            }
        }
        
        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="patient"></param>
        /// <returns></returns>
        public async Task<ResultDetail<List<IOrder>>> GetOrderList(IPatient patient)
        {
            HttpResult result = default;
            var postData = new GetPayListValidate();
            postData.CardNo = patient.CardNo;
            var httpItem = new HttpItem()
            {
                URL = $"{_options.Value.HisUrl}/GetValue",
                Method = "POST",
                ContentType = "application/json",
                Postdata = JsonConvert.SerializeObject(postData)
            };
            try
            {
                await Task.Run(() =>
                {
                    result = new HttpHelper().GetHtml(httpItem);
                });
                if (result.Html.TryJsonParse(out HisResult<List<GetPayListResponse>> response))
                {
                    if (response.ResultCode == "0")
                    {
                        var list = new List<IOrder>();
                        response.Data.ForEach(element =>
                        {
                            var item = new SysPrescription();
                            item.Amount = decimal.Parse(element.SSJE);
                            item.TradeNo = element.JSLSH_ID;
                            item.Code = element.JZLSH_ID;
                            item.Department = element.BM_MC;
                            item.Doctor = element.XM;
                            item.CardNo = patient.CardNo;
                            item.RawData = JsonConvert.SerializeObject(element);
                            list.Add(item);
                        });
                        return new ResultDetail<List<IOrder>>()
                        {
                            Message = response.ErrorMsg,
                            Request = httpItem.Postdata,
                            Response = result.Html,
                            Data = list
                        };
                    }
                    else
                    {
                        if (response.ErrorMsg.Contains("无相应收费数据"))
                        {
                            return new ResultDetail<List<IOrder>>()
                            {
                                Message = response.ErrorMsg,
                                Request = httpItem.Postdata,
                                Response = result.Html,
                                Data = new List<IOrder>()
                            };
                        }
                        return new ResultDetail<List<IOrder>>()
                        {
                            Code = 1,
                            Message = response.ErrorMsg,
                            Request = httpItem.Postdata,
                            Response = result.Html
                        };
                    }
                }
                return new ResultDetail<List<IOrder>>()
                {
                    Code = 1,
                    Message = "查询缴费清单失败, 返回数据解析异常.",
                    Request = httpItem.Postdata,
                    Response = result.Html
                };
            }
            catch (Exception e)
            {
                return new ResultDetail<List<IOrder>>()
                {
                    Code = 1,
                    Message = $"查询缴费清单异常:{JsonConvert.SerializeObject(e)}",
                    Request = httpItem.Postdata
                };
            }
        }

        /// <summary>
        /// 充值
        /// </summary>
        /// <param name="pay"></param>
        /// <param name="client"></param>
        /// <param name="operator"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Task<ResultDetail<bool>> AddCredit(SysPay pay, SysClient client, SysOperator @operator)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 生成就诊号
        /// </summary>
        /// <param name="patient"></param>
        /// <returns></returns>
        public async Task<ResultDetail<string>> CreateTreatmentNo(IPatient patient)
        {
            var postData = new TreatmentRequest();
            postData.IdCard = patient.IdCardNo;
            postData.Name = patient.Name;
            postData.Phone = patient.Phone.IsNullOrWhiteSpace() ? "0391-6652600" : patient.Phone;
            var item = new HttpItem();
            item.URL = $"{_options.Value.TreatmentUrl}/ld/common/v1/crown?method=createCrownPatInfo";
            item.Method = "POST";
            item.ContentType = "application/json";
            item.Postdata = JsonConvert.SerializeObject(postData);
            HttpResult result = default;
            try
            {
                await Task.Run(() =>
                {
                    result = new HttpHelper().GetHtml(item);
                });
                if (result.Html.TryJsonParse(out TreatmentResult response))
                {
                    if (response.Code == 1)
                    {
                        if (response.Data.TryJsonParse(out TreatmentResponse treatmentResponse))
                        {
                            if (!treatmentResponse.TreatmentNo.IsNullOrWhiteSpace())
                            {
                                return new ResultDetail<string>
                                {
                                    Data = treatmentResponse.TreatmentNo.Trim(),
                                    Message = treatmentResponse.ResponseMsg,
                                    Request = item.Postdata,
                                    Response = result.Html
                                };
                            }
                        }
                    }
                }
                return new ResultDetail<string>
                {
                    Code = 1,
                    Message = "生成就诊号失败",
                    Request = item.Postdata,
                    Response = result.Html
                };
            }
            catch (Exception e)
            {
                return new ResultDetail<string>
                {
                    Code = 1,
                    Message = $"生成就诊号异常:{JsonConvert.SerializeObject(e)}",
                    Request = item.Postdata,
                    Response = result?.Html
                };
            }
        }

        /// <summary>
        /// 获取收费项目列表
        /// </summary>
        /// <returns></returns>
        public async Task<ResultDetail<SysMedicalProject[]>> GetProjectList()
        {
            HttpResult result = default;
            var item = new HttpItem();
            item.URL = $"{_options.Value.TreatmentUrl}/ld/common/v1/crown?method=getCrownCheckItems";
            try
            {
                await Task.Run(() =>
                {
                    result = new HttpHelper().GetHtml(item);
                });
                if (result.Html.TryJsonParse(out TreatmentResult response))
                {
                    if (response.Code == 1)
                    {
                        if (response.Data.TryJsonParse(out ProjectResponse[] projectResponse) && projectResponse.Length > 0)
                        {
                            return new ResultDetail<SysMedicalProject[]>
                            {
                                Data = projectResponse
                                    .Select(e => new SysMedicalProject{Price = e.Price, Name = e.ProjectName, Code = e.ProjectNo})
                                    .ToArray(),
                                Response = result.Html
                            };
                        }
                    }
                }
                return new ResultDetail<SysMedicalProject[]>
                {
                    Code = 1,
                    Message = "获取项目列表失败",
                    Response = result.Html
                };
            }
            catch (Exception e)
            {
                return new ResultDetail<SysMedicalProject[]>
                {
                    Code = 1,
                    Message = $"获取项目列表失败异常:{JsonConvert.SerializeObject(e)}",
                    Response = result?.Html
                };
            }
        }

        /// <summary>
        /// 生成缴费单
        /// </summary>
        /// <param name="patientId">患者ID</param>
        /// <param name="treatmentNo">就诊流水号</param>
        /// <param name="projectNo">项目编号</param>
        /// <param name="qty"></param>
        /// <returns></returns>
        private async Task<ResultDetail<bool>> CreateOrder(string patientId, string treatmentNo, string projectNo, int qty = 1)
        {
            var postData = new CreateOrderRequest
            {
                PatientId = patientId,
                TreatmentNo = treatmentNo,
                ProjectNo = projectNo,
                Number = qty
            };
            var item = new HttpItem();
            item.URL = $"{_options.Value.TreatmentUrl}/ld/common/v1/crown?method=orderCrownItem";
            item.Method = "POST";
            item.ContentType = "application/json";
            item.Postdata = JsonConvert.SerializeObject(postData);
            HttpResult result = default;
            try
            {
                await Task.Run(() =>
                {
                    result = new HttpHelper().GetHtml(item);
                });
                if (result.Html.TryJsonParse(out TreatmentResult response))
                {
                    if (response.Code == 1)
                    {
                        return new ResultDetail<bool>()
                        {
                            Data = true,
                            Response = result.Html,
                            Request = item.Postdata
                        };
                    }
                }
                return new ResultDetail<bool>()
                {
                    Message = "生成缴费单失败",
                    Code = 1,
                    Response = result.Html,
                    Request = item.Postdata
                };
            }
            catch (Exception e)
            {
                return new ResultDetail<bool>()
                {
                    Code = 1,
                    Response = result?.Html,
                    Request = item.Postdata,
                    Message = $"生成缴费单异常:{JsonConvert.SerializeObject(e)}"
                };
            }
        }

        /// <summary>
        /// 生成处方
        /// </summary>
        /// <param name="patient"></param>
        /// <param name="projectNo"></param>
        /// <param name="qty"></param>
        /// <returns></returns>
        public async Task<ResultDetail<IOrder>> CreateOrder(IPatient patient, string projectNo, int qty = 1)
        {
            string treatmentNo;
            {
                var result = await this.CreateTreatmentNo(patient);
                if (result.Code != 200)
                {
                    return new ResultDetail<IOrder>()
                    {
                        Message = $"生成处方失败|{result.Message}",
                        Code = result.Code,
                        Response = result.Response,
                        Request = result.Request,
                        StatusCode = result.StatusCode
                    };
                }
                treatmentNo = result.Data;
            }
            {
                var result = await this.CreateOrder(patient.HisCode, treatmentNo, projectNo, qty);
                if (result.Code != 200)
                {
                    return new ResultDetail<IOrder>()
                    {
                        Message = $"生成处方失败|{result.Message}",
                        Code = result.Code,
                        Response = result.Response,
                        Request = result.Request,
                        StatusCode = result.StatusCode
                    };
                }
            }
            {
                var result = await this.GetOrderList(patient);
                if (result.Code != 200)
                {
                    return new ResultDetail<IOrder>()
                    {
                        Message = $"生成处方成功, 获取待缴费处方列表失败|{result.Message}",
                        Code = result.Code,
                        Response = result.Response,
                        Request = result.Request,
                        StatusCode = result.StatusCode
                    };
                }
                var order = result.Data.FirstOrDefault(e => e.Code == treatmentNo);
                if (order == null)
                {
                    return new ResultDetail<IOrder>()
                    {
                        Message = $"生成处方成功, 获取待缴费处方失败|{result.Message}",
                        Code = result.Code,
                        Response = result.Response,
                        Request = result.Request,
                        StatusCode = result.StatusCode
                    };
                }
                return new ResultDetail<IOrder>()
                {
                    Data = order,
                    Response = result.Response,
                    Request = result.Request,
                    StatusCode = result.StatusCode
                };
            }
        }

        /// <summary>
        /// HIS发起退款
        /// </summary>
        /// <param name="prescription"></param>
        /// <returns></returns>
        public async Task<ResultDetail<bool>> Refund(SysPrescription prescription)
        {
            HttpResult result = default;
            var postData = new HisRefundRequest();
            postData.JieSuanNo = prescription.TradeNo;
            postData.UserId = _wtm.LoginUserInfo.ITCode;
            var httpItem = new HttpItem
            {
                URL = $"{_options.Value.HisUrl}/GetValue",
                Method = "POST",
                ContentType = "application/json",
                Postdata = JsonConvert.SerializeObject(postData)
            };
            try
            {
                await Task.Run(() =>
                {
                    result = new HttpHelper().GetHtml(httpItem);
                });
                if (result.Html.TryJsonParse(out HisResult<object> response))
                {
                    if (response.ResultCode == "0")
                    {
                        return new ResultDetail<bool>()
                        {
                            Message = response.ErrorMsg,
                            Request = httpItem.Postdata,
                            Response = result.Html
                        };
                    }
                    else
                    {
                        return new ResultDetail<bool>()
                        {
                            Code = 1,
                            Message = response.ErrorMsg,
                            Request = httpItem.Postdata,
                            Response = result.Html
                        };
                    }
                }
                return new ResultDetail<bool>()
                {
                    Code = 1,
                    Message = "退款失败, 返回数据解析异常.",
                    Request = httpItem.Postdata,
                    Response = result.Html
                };
            }
            catch (Exception e)
            {
                return new ResultDetail<bool>()
                {
                    Code = 1,
                    Message = $"退款失败:{JsonConvert.SerializeObject(e)}",
                    Request = httpItem.Postdata
                };
            }
        }

        private class TreatmentRequest
        {
            [JsonProperty("name")]
            public string Name { get; set; }

            [JsonProperty("Idcard_type")]
            public string CardType { get; set; } = "1";

            [JsonProperty("Idcard_value")]
            public string IdCard { get; set; }

            [JsonProperty(PropertyName = "Phone", NullValueHandling = NullValueHandling.Ignore)]
            public string Phone { get; set; }
        }

        private class TreatmentResponse
        {
            [JsonProperty("response_code")]
            public string ResponseCode { get; set; }

            [JsonProperty("response_msg")]
            public string ResponseMsg { get; set; }

            [JsonProperty("record_no")]
            public string RecordNo { get; set; }

            [JsonProperty("treatment_no")]
            public string TreatmentNo { get; set; }
        }

        private class TreatmentResult
        {
            public int Code { get; set; }

            public string Msg { get; set; }
            public string Data { get; set; }
        }

        private class ProjectResponse : ProjectInfo
        {
            [JsonProperty("PROJECT_NO")]
            public new string ProjectNo { get; set; }

            [JsonProperty("FEE")]
            public new decimal Price { get; set; }

            [JsonProperty("PROJECT_NAME")]
            public new string ProjectName { get; set; }
        }

        public class CreateOrderRequest
        {
            [JsonProperty("record_no")]
            public string PatientId { get; set; }

            [JsonProperty("treatment_no")]
            public string TreatmentNo { get; set; }

            [JsonProperty("project_no_lists")]
            public string ProjectNo { get; set; }
            public int Number { get; set; } = 1;
        }

        private class HisRefundRequest
        {
            /// <summary>
            /// 业务编号
            /// </summary>
            [JsonProperty("TranCode")]
            public string TranCode { get; set; } = "0038";

            /// <summary>
            /// 卡号
            /// </summary>
            [JsonProperty("JSLSH")]
            public string JieSuanNo { get; set; }

            /// <summary>
            /// 用户ID
            /// </summary>
            [JsonProperty("UserId")]
            public string UserId { get; set; }
        }
        
        private class HisPayResult
        {
            public string RetMsg { get; set; }
        }
    }
}
